#ifdef	ADI_OLD

#include "InputSequences.h"

InputSequences::InputSequences(const char *_filename, uint _pageSize) :
		flags(FIRST_SEQ),
		pageSize(_pageSize),
		sequences(),
		filename(_filename),
		bytesRead(0),
		buffPos(0),
		nextName("")
{
}

InputSequences::~InputSequences()
{
	// Delete all sequences
	for (vector<InputSequence*>::iterator it = sequences.begin(); it < sequences.end(); it++)
		delete (*it);
}

#ifdef	ADI_OLD
uint InputSequences::addOneSequence(ifstream &inputFile)
{
	bool	nameRead = true;
	char seqBuffer[BUFFER_SIZE];
	uint seqBufPos = 0;
	bool readOneSeq = false;
	
	/* setting up the new sequence */
	InputSequence *newSeq = new InputSequence();
	sequences.push_back(newSeq);
	newSeq->setName(nextName);

	while (1)
	{
		while (buffPos < bytesRead)
		{
			if (buffer[buffPos] == '>')
			{
				nameRead = false;
				nextName = "";
			}
			else
			{
				/* Just read the sequence name until the first new-line */
				if (!nameRead)
				{
					if (buffer[buffPos] == '\n')
					{
						nameRead = true;
						if (isFirstSeq(flags))
						{
							newSeq->setName(nextName);
							notFirstSeq(flags);
						}
						else
						{
							readOneSeq = true;
							break;
						}
					}
					else
					{
						nextName = nextName + buffer[buffPos];
					}
				}
				else
				{
					if (buffer[buffPos] != '\n')
					{
						seqBuffer[seqBufPos++] = buffer[buffPos];
						if (seqBufPos % BUFFER_SIZE == 0)
						{
							newSeq->append(seqBuffer, BUFFER_SIZE);
							seqBufPos = 0;
						}
					}
				}
			}
			buffPos++;
		}
		if (!readOneSeq && !inputFile.eof())
		{
			inputFile.read(&buffer[0], BUFFER_SIZE);
			bytesRead = inputFile.gcount();
			buffPos = 0;
		}
		else
			break;
	}
	
	/* finished reading, add the last info the the current sequence */
	if (seqBufPos != 0)
		newSeq->append(seqBuffer, seqBufPos);
		
	if (buffPos >= bytesRead && inputFile.eof())
		flags |= DONE_READING;
		
	return sequences.size() - 1;
}
#endif	/* ADI_OLD */

void InputSequences::parseFile()
{
	bool first = true;
	bool nameRead = false;
	uint seqBufPos = 0;
	string curName = "";
	//sequences.reserve(10);
	InputSequence *curSeq = new InputSequence();
	sequences.push_back(curSeq);
	uint offset;

	int fd = open(_fileName, O_RDONLY);
	if (fd == -1)
	{
		perror("Error reading reference file");
		exit(1);
	}

	// Fetch file size
	off_t fileSize = lseek(fd, 0, SEEK_END);
	lseek(fd, 0, SEEK_SET);


	while (offset < fileSize)
	{
		// Map the file to the memory
		char *data = (char *)mmap(NULL, pageSize, PROT_READ, MAP_PRIVATE, fd, offset);

		char *dataEnd;
		if (offset + pageSize < fileSize)
			dataEnd = data + pageSize;
		else
			dataEnd = data + (fileSize - offset);

		for (char *p = data; p < dataEnd; p++)
		{
			if (*p == '>')
			{
				if (!first)
				{
					/* Starting a new input sequence */
					nameRead = false;
					curSeq->append(seqBuffer, seqBufPos);
					seqBufPos = 0;
					curSeq = new InputSequence();
					sequences.push_back(curSeq);
				}
				else
					first = false;
			}
			else
			{
				/* Just read the sequence name until the first new-line */
				if (!nameRead)
				{
					if (buffer[i] == '\n')
					{
						nameRead = true;
						curSeq->setName(curName);
						curName = "";
					}
					else
					{
						curName = curName + buffer[i];
					}
				}
				else
				{
					if (buffer[i] != '\n')
					{
						seqBuffer[seqBufPos++] = buffer[i];
						if (seqBufPos % BUFFER_SIZE == 0)
						{
							curSeq->append(seqBuffer, BUFFER_SIZE);
							seqBufPos = 0;
						}
					}
				}
			}
		}
		/* finished reading, add the last info the the current sequence */
		if (seqBufPos != 0)
			curSeq->append(seqBuffer, seqBufPos);

		munmap(data, pageSize);
	}


	while (!inputFile.eof())
	{
		inputFile.read(&buffer[0], BUFFER_SIZE);
		streamsize bytesRead = inputFile.gcount();
		for (int i = 0; i < bytesRead; i++)
		{
			if (buffer[i] == '>')
			{
				if (!first)
				{
					/* Starting a new input sequence */
					nameRead = false;
					curSeq->append(seqBuffer, seqBufPos);
					seqBufPos = 0;
					curSeq = new InputSequence();
					sequences.push_back(curSeq);
				}
				else
					first = false;
//				sequences[curSeq] = InputSequence();
			}
			else
			{
				/* Just read the sequence name until the first new-line */
				if (!nameRead)
				{
					if (buffer[i] == '\n')
					{
						nameRead = true;
						curSeq->setName(curName);
						curName = "";
					}
					else
					{
						curName = curName + buffer[i];
					}
				}
				else
				{
					if (buffer[i] != '\n')
					{
						seqBuffer[seqBufPos++] = buffer[i];
						if (seqBufPos % BUFFER_SIZE == 0)
						{
							curSeq->append(seqBuffer, BUFFER_SIZE);
							seqBufPos = 0;
						}
					}
				}
			}
		}


	}
	/* finished reading, add the last info the the current sequence */
	if (seqBufPos != 0)
		curSeq->append(seqBuffer, seqBufPos);

}


//void InputSequences::addSequences()
//{
//	bool first = true;
//	bool nameRead = false;
//	uint seqBufPos = 0;
//	char seqBuffer[BUFFER_SIZE];
//	string curName = "";
//	uint curSeq = 0;
//	//sequences.reserve(10);
//	sequences.push_back(InputSequence());

//	while (!inputFile.eof())
//	{
//		inputFile.read(&buffer[0], BUFFER_SIZE);
//		streamsize bytesRead = inputFile.gcount();
//		for (int i = 0; i < bytesRead; i++)
//		{
//			if (buffer[i] == '>')
//			{
//				if (!first)
//				{
//					/* Starting a new input sequence */
//					nameRead = false;
//					sequences[curSeq].append(seqBuffer, seqBufPos);
//					seqBufPos = 0;
//					curSeq++;
//					sequences.push_back(InputSequence());
//				}
//				else
//					first = false;
////				sequences[curSeq] = InputSequence();
//			}
//			else
//			{
//				/* Just read the sequence name until the first new-line */
//				if (!nameRead)
//				{
//					if (buffer[i] == '\n')
//					{
//						nameRead = true;
//						sequences[curSeq].setName(curName);
//						curName = "";
//					}
//					else
//					{
//						curName = curName + buffer[i];
//					}
//				}
//				else
//				{
//					if (buffer[i] != '\n')
//					{
//						seqBuffer[seqBufPos++] = buffer[i];
//						if (seqBufPos % BUFFER_SIZE == 0)
//						{
//							sequences[curSeq].append(seqBuffer, BUFFER_SIZE);
//							seqBufPos = 0;
//						}
//					}
//				}
//			}
//		}


//	}
//	/* finished reading, add the last info the the current sequence */
//	if (seqBufPos != 0)
//		sequences[curSeq].append(seqBuffer, seqBufPos);

//}

bool InputSequences::trySort()
{
	uint areSorted = 0;
	
	for (vector<InputSequence*>::iterator currSeq=sequences.begin() ; currSeq < sequences.end(); currSeq++)
		if ((*currSeq)->trySort())
			areSorted++;

	if ((flags & DONE_READING) && areSorted == sequences.size())
		return true;
	return false;
}

uint InputSequences::getSequencesNum() const
{
	return sequences.size();
}

#ifdef DEBUG

void InputSequences::print() const
{
	for (vector<InputSequence*>::const_iterator it = sequences.begin(); it < sequences.end(); it++)
	{
		(*it)->print();
	}
}

#endif /* DEBUG */

#endif	/* ADI_OLD */
